using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Expression.Drawing.Core
{
	public static class GeometryHelper
	{
		internal static Rect Bounds(this Size size)
		{
			return new Rect(0.0, 0.0, size.get_Width(), size.get_Height());
		}
		internal static bool HasValidArea(this Size size)
		{
			return size.get_Width() > 0.0 && size.get_Height() > 0.0 && !double.IsInfinity(size.get_Width()) && !double.IsInfinity(size.get_Height());
		}
		internal static Size Size(this Rect rect)
		{
			return new Size(rect.get_Width(), rect.get_Height());
		}
		internal static Point TopLeft(this Rect rect)
		{
			return new Point(rect.get_Left(), rect.get_Top());
		}
		internal static Point TopRight(this Rect rect)
		{
			return new Point(rect.get_Right(), rect.get_Top());
		}
		internal static Point BottomRight(this Rect rect)
		{
			return new Point(rect.get_Right(), rect.get_Bottom());
		}
		internal static Point BottomLeft(this Rect rect)
		{
			return new Point(rect.get_Left(), rect.get_Bottom());
		}
		internal static Point Center(this Rect rect)
		{
			return new Point(rect.get_X() + rect.get_Width() / 2.0, rect.get_Y() + rect.get_Height() / 2.0);
		}
		internal static Thickness Subtract(this Rect lhs, Rect rhs)
		{
			return new Thickness(rhs.get_Left() - lhs.get_Left(), rhs.get_Top() - lhs.get_Top(), lhs.get_Right() - rhs.get_Right(), lhs.get_Bottom() - rhs.get_Bottom());
		}
		internal static Rect Resize(this Rect rect, double ratio)
		{
			return rect.Resize(ratio, ratio);
		}
		internal static Rect Resize(this Rect rect, double ratioX, double ratioY)
		{
			Point point = rect.Center();
			double num = rect.get_Width() * ratioX;
			double num2 = rect.get_Height() * ratioY;
			return new Rect(point.get_X() - num / 2.0, point.get_Y() - num2 / 2.0, num, num2);
		}
		internal static Rect ActualBounds(this FrameworkElement element)
		{
			return new Rect(0.0, 0.0, element.get_ActualWidth(), element.get_ActualHeight());
		}
		internal static Thickness Negate(this Thickness thickness)
		{
			return new Thickness(-thickness.get_Left(), -thickness.get_Top(), -thickness.get_Right(), -thickness.get_Bottom());
		}
		internal static Vector Subtract(this Point lhs, Point rhs)
		{
			return new Vector(lhs.get_X() - rhs.get_X(), lhs.get_Y() - rhs.get_Y());
		}
		internal static Point Plus(this Point lhs, Point rhs)
		{
			return new Point(lhs.get_X() + rhs.get_X(), lhs.get_Y() + rhs.get_Y());
		}
		internal static Point Minus(this Point lhs, Point rhs)
		{
			return new Point(lhs.get_X() - rhs.get_X(), lhs.get_Y() - rhs.get_Y());
		}
		internal static Vector Normalized(this Vector vector)
		{
			Vector vector2 = new Vector(vector.X, vector.Y);
			double length = vector2.Length;
			if (MathHelper.IsVerySmall(length))
			{
				return new Vector(0.0, 1.0);
			}
			return vector2 / length;
		}
		internal static void ApplyTransform(this IList<Point> points, GeneralTransform transform)
		{
			for (int i = 0; i < points.get_Count(); i++)
			{
				points.set_Item(i, transform.Transform(points.get_Item(i)));
			}
		}
		public static PathGeometry ConvertToPathGeometry(string abbreviatedGeometry)
		{
			return PathGeometryHelper.ConvertToPathGeometry(abbreviatedGeometry);
		}
		public static void FlattenFigure(PathFigure figure, IList<Point> points, double tolerance)
		{
			PathFigureHelper.FlattenFigure(figure, points, tolerance, false);
		}
		internal static Point Lerp(Point pointA, Point pointB, double alpha)
		{
			return new Point(MathHelper.Lerp(pointA.get_X(), pointB.get_X(), alpha), MathHelper.Lerp(pointA.get_Y(), pointB.get_Y(), alpha));
		}
		internal static Vector Lerp(Vector vectorA, Vector vectorB, double alpha)
		{
			return new Vector(MathHelper.Lerp(vectorA.X, vectorB.X, alpha), MathHelper.Lerp(vectorA.Y, vectorB.Y, alpha));
		}
		internal static Rect Inflate(Rect rect, double offset)
		{
			return GeometryHelper.Inflate(rect, new Thickness(offset));
		}
		internal static Rect Inflate(Rect rect, double offsetX, double offsetY)
		{
			return GeometryHelper.Inflate(rect, new Thickness(offsetX, offsetY, offsetX, offsetY));
		}
		internal static Rect Inflate(Rect rect, Size size)
		{
			return GeometryHelper.Inflate(rect, new Thickness(size.get_Width(), size.get_Height(), size.get_Width(), size.get_Height()));
		}
		internal static Rect Inflate(Rect rect, Thickness thickness)
		{
			double num = rect.get_Width() + thickness.get_Left() + thickness.get_Right();
			double num2 = rect.get_Height() + thickness.get_Top() + thickness.get_Bottom();
			double num3 = rect.get_X() - thickness.get_Left();
			if (num < 0.0)
			{
				num3 += num / 2.0;
				num = 0.0;
			}
			double num4 = rect.get_Y() - thickness.get_Top();
			if (num2 < 0.0)
			{
				num4 += num2 / 2.0;
				num2 = 0.0;
			}
			return new Rect(num3, num4, num, num2);
		}
		internal static Point GetArcPoint(double degree)
		{
			double num = degree * 3.1415926535897931 / 180.0;
			return new Point(0.5 + 0.5 * Math.Sin(num), 0.5 - 0.5 * Math.Cos(num));
		}
		internal static Point GetArcPoint(double degree, Rect bound)
		{
			Point arcPoint = GeometryHelper.GetArcPoint(degree);
			return GeometryHelper.RelativeToAbsolutePoint(bound, arcPoint);
		}
		internal static double GetArcAngle(Point point)
		{
			return Math.Atan2(point.get_Y() - 0.5, point.get_X() - 0.5) * 180.0 / 3.1415926535897931 + 90.0;
		}
		internal static double GetArcAngle(Point point, Rect bound)
		{
			Point point2 = GeometryHelper.AbsoluteToRelativePoint(bound, point);
			return GeometryHelper.GetArcAngle(point2);
		}
		internal static Transform RelativeTransform(Rect from, Rect to)
		{
			Point point = from.Center();
			Point point2 = to.Center();
			TransformGroup transformGroup = new TransformGroup();
			TransformGroup arg_C9_0 = transformGroup;
			TransformCollection transformCollection = new TransformCollection();
			PresentationFrameworkCollection<Transform> arg_43_0 = transformCollection;
			TranslateTransform translateTransform = new TranslateTransform();
			translateTransform.set_X(-point.get_X());
			translateTransform.set_Y(-point.get_Y());
			arg_43_0.Add(translateTransform);
			PresentationFrameworkCollection<Transform> arg_98_0 = transformCollection;
			ScaleTransform scaleTransform = new ScaleTransform();
			scaleTransform.set_ScaleX(MathHelper.SafeDivide(to.get_Width(), from.get_Width(), 1.0));
			scaleTransform.set_ScaleY(MathHelper.SafeDivide(to.get_Height(), from.get_Height(), 1.0));
			arg_98_0.Add(scaleTransform);
			PresentationFrameworkCollection<Transform> arg_C3_0 = transformCollection;
			TranslateTransform translateTransform2 = new TranslateTransform();
			translateTransform2.set_X(point2.get_X());
			translateTransform2.set_Y(point2.get_Y());
			arg_C3_0.Add(translateTransform2);
			arg_C9_0.set_Children(transformCollection);
			return transformGroup;
		}
		internal static GeneralTransform RelativeTransform(UIElement from, UIElement to)
		{
			if (from != null && to != null)
			{
				GeneralTransform result;
				try
				{
					result = from.TransformToVisual(to);
				}
				catch (ArgumentException)
				{
					result = null;
				}
				catch (InvalidOperationException)
				{
					result = null;
				}
				return result;
			}
			return null;
		}
		internal static Point SafeTransform(GeneralTransform transform, Point point)
		{
			Point result = point;
			if (transform != null && transform.TryTransform(point, ref result))
			{
				return result;
			}
			return point;
		}
		internal static Point RelativeToAbsolutePoint(Rect bound, Point relative)
		{
			return new Point(bound.get_X() + relative.get_X() * bound.get_Width(), bound.get_Y() + relative.get_Y() * bound.get_Height());
		}
		internal static Point AbsoluteToRelativePoint(Rect bound, Point absolute)
		{
			return new Point(MathHelper.SafeDivide(absolute.get_X() - bound.get_X(), bound.get_Width(), 1.0), MathHelper.SafeDivide(absolute.get_Y() - bound.get_Y(), bound.get_Height(), 1.0));
		}
		internal static Rect GetStretchBound(Rect logicalBound, Stretch stretch, Size aspectRatio)
		{
			if (stretch == null)
			{
				stretch = 1;
			}
			if (stretch != 1 && aspectRatio.HasValidArea())
			{
				Point point = logicalBound.Center();
				if (stretch == 2)
				{
					if (aspectRatio.get_Width() * logicalBound.get_Height() < logicalBound.get_Width() * aspectRatio.get_Height())
					{
						logicalBound.set_Width(logicalBound.get_Height() * aspectRatio.get_Width() / aspectRatio.get_Height());
					}
					else
					{
						logicalBound.set_Height(logicalBound.get_Width() * aspectRatio.get_Height() / aspectRatio.get_Width());
					}
				}
				else
				{
					if (stretch == 3)
					{
						if (aspectRatio.get_Width() * logicalBound.get_Height() < logicalBound.get_Width() * aspectRatio.get_Height())
						{
							logicalBound.set_Height(logicalBound.get_Width() * aspectRatio.get_Height() / aspectRatio.get_Width());
						}
						else
						{
							logicalBound.set_Width(logicalBound.get_Height() * aspectRatio.get_Width() / aspectRatio.get_Height());
						}
					}
				}
				return new Rect(point.get_X() - logicalBound.get_Width() / 2.0, point.get_Y() - logicalBound.get_Height() / 2.0, logicalBound.get_Width(), logicalBound.get_Height());
			}
			return logicalBound;
		}
		internal static Point Midpoint(Point lhs, Point rhs)
		{
			return new Point((lhs.get_X() + rhs.get_X()) / 2.0, (lhs.get_Y() + rhs.get_Y()) / 2.0);
		}
		internal static double Dot(Vector lhs, Vector rhs)
		{
			return lhs.X * rhs.X + lhs.Y * rhs.Y;
		}
		internal static double Dot(Point lhs, Point rhs)
		{
			return lhs.get_X() * rhs.get_X() + lhs.get_Y() * rhs.get_Y();
		}
		internal static double Distance(Point lhs, Point rhs)
		{
			double num = lhs.get_X() - rhs.get_X();
			double num2 = lhs.get_Y() - rhs.get_Y();
			return Math.Sqrt(num * num + num2 * num2);
		}
		internal static double SquaredDistance(Point lhs, Point rhs)
		{
			double num = lhs.get_X() - rhs.get_X();
			double num2 = lhs.get_Y() - rhs.get_Y();
			return num * num + num2 * num2;
		}
		internal static double Determinant(Point lhs, Point rhs)
		{
			return lhs.get_X() * rhs.get_Y() - lhs.get_Y() * rhs.get_X();
		}
		internal static Vector Normal(Point lhs, Point rhs)
		{
			return new Vector(lhs.get_Y() - rhs.get_Y(), rhs.get_X() - lhs.get_X()).Normalized();
		}
		internal static Vector Perpendicular(this Vector vector)
		{
			return new Vector(-vector.Y, vector.X);
		}
		internal static bool GeometryEquals(Geometry firstGeometry, Geometry secondGeometry)
		{
			if (firstGeometry == secondGeometry)
			{
				return true;
			}
			if (firstGeometry == null || secondGeometry == null)
			{
				return false;
			}
			if (firstGeometry.GetType() != secondGeometry.GetType())
			{
				return false;
			}
			if (!firstGeometry.get_Transform().TransformEquals(secondGeometry.get_Transform()))
			{
				return false;
			}
			PathGeometry pathGeometry = firstGeometry as PathGeometry;
			PathGeometry pathGeometry2 = secondGeometry as PathGeometry;
			if (pathGeometry != null && pathGeometry2 != null)
			{
				string text = pathGeometry.ToString();
				string text2 = pathGeometry2.ToString();
				if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text2))
				{
					return text == text2;
				}
				return GeometryHelper.PathGeometryEquals(pathGeometry, pathGeometry2);
			}
			else
			{
				LineGeometry lineGeometry = firstGeometry as LineGeometry;
				LineGeometry lineGeometry2 = secondGeometry as LineGeometry;
				if (lineGeometry != null && lineGeometry2 != null)
				{
					return GeometryHelper.LineGeometryEquals(lineGeometry, lineGeometry2);
				}
				RectangleGeometry rectangleGeometry = firstGeometry as RectangleGeometry;
				RectangleGeometry rectangleGeometry2 = secondGeometry as RectangleGeometry;
				if (rectangleGeometry != null && rectangleGeometry2 != null)
				{
					return GeometryHelper.RectangleGeometryEquals(rectangleGeometry, rectangleGeometry2);
				}
				EllipseGeometry ellipseGeometry = firstGeometry as EllipseGeometry;
				EllipseGeometry ellipseGeometry2 = secondGeometry as EllipseGeometry;
				if (ellipseGeometry != null && ellipseGeometry2 != null)
				{
					return GeometryHelper.EllipseGeometryEquals(ellipseGeometry, ellipseGeometry2);
				}
				GeometryGroup geometryGroup = firstGeometry as GeometryGroup;
				GeometryGroup geometryGroup2 = secondGeometry as GeometryGroup;
				return geometryGroup != null && geometryGroup2 != null && GeometryHelper.GeometryGroupEquals(geometryGroup, geometryGroup2);
			}
		}
		internal static bool PathGeometryEquals(PathGeometry firstGeometry, PathGeometry secondGeometry)
		{
			if (firstGeometry.get_FillRule() != secondGeometry.get_FillRule())
			{
				return false;
			}
			if (firstGeometry.get_Figures().get_Count() != secondGeometry.get_Figures().get_Count())
			{
				return false;
			}
			for (int i = 0; i < firstGeometry.get_Figures().get_Count(); i++)
			{
				if (!GeometryHelper.PathFigureEquals(firstGeometry.get_Figures().get_Item(i), secondGeometry.get_Figures().get_Item(i)))
				{
					return false;
				}
			}
			return true;
		}
		private static bool PathFigureEquals(PathFigure firstFigure, PathFigure secondFigure)
		{
			if (firstFigure.get_IsClosed() != secondFigure.get_IsClosed())
			{
				return false;
			}
			if (firstFigure.get_IsFilled() != secondFigure.get_IsFilled())
			{
				return false;
			}
			if (firstFigure.get_StartPoint() != secondFigure.get_StartPoint())
			{
				return false;
			}
			for (int i = 0; i < firstFigure.get_Segments().get_Count(); i++)
			{
				if (!GeometryHelper.PathSegmentEquals(firstFigure.get_Segments().get_Item(i), secondFigure.get_Segments().get_Item(i)))
				{
					return false;
				}
			}
			return true;
		}
		private static bool PathSegmentEquals(PathSegment firstSegment, PathSegment secondSegment)
		{
			if (firstSegment == secondSegment)
			{
				return true;
			}
			if (firstSegment == null || secondSegment == null)
			{
				return false;
			}
			if (firstSegment.GetType() != secondSegment.GetType())
			{
				return false;
			}
			if (firstSegment.IsStroked() != secondSegment.IsStroked())
			{
				return false;
			}
			if (firstSegment.IsSmoothJoin() != secondSegment.IsSmoothJoin())
			{
				return false;
			}
			LineSegment lineSegment = firstSegment as LineSegment;
			LineSegment lineSegment2 = secondSegment as LineSegment;
			if (lineSegment != null && lineSegment2 != null)
			{
				return GeometryHelper.LineSegmentEquals(lineSegment, lineSegment2);
			}
			BezierSegment bezierSegment = firstSegment as BezierSegment;
			BezierSegment bezierSegment2 = secondSegment as BezierSegment;
			if (bezierSegment != null && bezierSegment2 != null)
			{
				return GeometryHelper.BezierSegmentEquals(bezierSegment, bezierSegment2);
			}
			QuadraticBezierSegment quadraticBezierSegment = firstSegment as QuadraticBezierSegment;
			QuadraticBezierSegment quadraticBezierSegment2 = secondSegment as QuadraticBezierSegment;
			if (quadraticBezierSegment != null && quadraticBezierSegment2 != null)
			{
				return GeometryHelper.QuadraticBezierSegmentEquals(quadraticBezierSegment, quadraticBezierSegment2);
			}
			ArcSegment arcSegment = firstSegment as ArcSegment;
			ArcSegment arcSegment2 = secondSegment as ArcSegment;
			if (arcSegment != null && arcSegment2 != null)
			{
				return GeometryHelper.ArcSegmentEquals(arcSegment, arcSegment2);
			}
			PolyLineSegment polyLineSegment = firstSegment as PolyLineSegment;
			PolyLineSegment polyLineSegment2 = secondSegment as PolyLineSegment;
			if (polyLineSegment != null && polyLineSegment2 != null)
			{
				return GeometryHelper.PolyLineSegmentEquals(polyLineSegment, polyLineSegment2);
			}
			PolyBezierSegment polyBezierSegment = firstSegment as PolyBezierSegment;
			PolyBezierSegment polyBezierSegment2 = secondSegment as PolyBezierSegment;
			if (polyBezierSegment != null && polyBezierSegment2 != null)
			{
				return GeometryHelper.PolyBezierSegmentEquals(polyBezierSegment, polyBezierSegment2);
			}
			PolyQuadraticBezierSegment polyQuadraticBezierSegment = firstSegment as PolyQuadraticBezierSegment;
			PolyQuadraticBezierSegment polyQuadraticBezierSegment2 = secondSegment as PolyQuadraticBezierSegment;
			return polyQuadraticBezierSegment != null && polyQuadraticBezierSegment2 != null && GeometryHelper.PolyQuadraticBezierSegmentEquals(polyQuadraticBezierSegment, polyQuadraticBezierSegment2);
		}
		private static bool LineSegmentEquals(LineSegment firstLineSegment, LineSegment secondLineSegment)
		{
			return firstLineSegment.get_Point() == secondLineSegment.get_Point();
		}
		private static bool BezierSegmentEquals(BezierSegment firstBezierSegment, BezierSegment secondBezierSegment)
		{
			return firstBezierSegment.get_Point1() == secondBezierSegment.get_Point1() && firstBezierSegment.get_Point2() == secondBezierSegment.get_Point2() && firstBezierSegment.get_Point3() == secondBezierSegment.get_Point3();
		}
		private static bool QuadraticBezierSegmentEquals(QuadraticBezierSegment firstQuadraticBezierSegment, QuadraticBezierSegment secondQuadraticBezierSegment)
		{
			return firstQuadraticBezierSegment.get_Point1() == secondQuadraticBezierSegment.get_Point1() && firstQuadraticBezierSegment.get_Point1() == secondQuadraticBezierSegment.get_Point1();
		}
		private static bool ArcSegmentEquals(ArcSegment firstArcSegment, ArcSegment secondArcSegment)
		{
			return firstArcSegment.get_Point() == secondArcSegment.get_Point() && firstArcSegment.get_IsLargeArc() == secondArcSegment.get_IsLargeArc() && firstArcSegment.get_RotationAngle() == secondArcSegment.get_RotationAngle() && firstArcSegment.get_Size() == secondArcSegment.get_Size() && firstArcSegment.get_SweepDirection() == secondArcSegment.get_SweepDirection();
		}
		private static bool PolyLineSegmentEquals(PolyLineSegment firstPolyLineSegment, PolyLineSegment secondPolyLineSegment)
		{
			if (firstPolyLineSegment.get_Points().get_Count() != secondPolyLineSegment.get_Points().get_Count())
			{
				return false;
			}
			for (int i = 0; i < firstPolyLineSegment.get_Points().get_Count(); i++)
			{
				if (firstPolyLineSegment.get_Points().get_Item(i) != secondPolyLineSegment.get_Points().get_Item(i))
				{
					return false;
				}
			}
			return true;
		}
		private static bool PolyBezierSegmentEquals(PolyBezierSegment firstPolyBezierSegment, PolyBezierSegment secondPolyBezierSegment)
		{
			if (firstPolyBezierSegment.get_Points().get_Count() != secondPolyBezierSegment.get_Points().get_Count())
			{
				return false;
			}
			for (int i = 0; i < firstPolyBezierSegment.get_Points().get_Count(); i++)
			{
				if (firstPolyBezierSegment.get_Points().get_Item(i) != secondPolyBezierSegment.get_Points().get_Item(i))
				{
					return false;
				}
			}
			return true;
		}
		private static bool PolyQuadraticBezierSegmentEquals(PolyQuadraticBezierSegment firstPolyQuadraticBezierSegment, PolyQuadraticBezierSegment secondPolyQuadraticBezierSegment)
		{
			if (firstPolyQuadraticBezierSegment.get_Points().get_Count() != secondPolyQuadraticBezierSegment.get_Points().get_Count())
			{
				return false;
			}
			for (int i = 0; i < firstPolyQuadraticBezierSegment.get_Points().get_Count(); i++)
			{
				if (firstPolyQuadraticBezierSegment.get_Points().get_Item(i) != secondPolyQuadraticBezierSegment.get_Points().get_Item(i))
				{
					return false;
				}
			}
			return true;
		}
		private static bool EllipseGeometryEquals(EllipseGeometry firstGeometry, EllipseGeometry secondGeometry)
		{
			return firstGeometry.get_Center() == secondGeometry.get_Center() && firstGeometry.get_RadiusX() == secondGeometry.get_RadiusX() && firstGeometry.get_RadiusY() == secondGeometry.get_RadiusY();
		}
		private static bool RectangleGeometryEquals(RectangleGeometry firstGeometry, RectangleGeometry secondGeometry)
		{
			return firstGeometry.get_Rect() == secondGeometry.get_Rect() && firstGeometry.get_RadiusX() == secondGeometry.get_RadiusX() && firstGeometry.get_RadiusY() == secondGeometry.get_RadiusY();
		}
		private static bool LineGeometryEquals(LineGeometry firstGeometry, LineGeometry secondGeometry)
		{
			return firstGeometry.get_StartPoint() == secondGeometry.get_StartPoint() && firstGeometry.get_EndPoint() == secondGeometry.get_EndPoint();
		}
		private static bool GeometryGroupEquals(GeometryGroup firstGeometry, GeometryGroup secondGeometry)
		{
			if (firstGeometry.get_FillRule() != secondGeometry.get_FillRule())
			{
				return false;
			}
			if (firstGeometry.get_Children().get_Count() != secondGeometry.get_Children().get_Count())
			{
				return false;
			}
			for (int i = 0; i < firstGeometry.get_Children().get_Count(); i++)
			{
				if (!GeometryHelper.GeometryEquals(firstGeometry.get_Children().get_Item(i), secondGeometry.get_Children().get_Item(i)))
				{
					return false;
				}
			}
			return true;
		}
		internal static bool EnsureGeometryType<T>(out T result, ref Geometry value, Func<T> factory) where T : Geometry
		{
			result = (value as T);
			if (result == null)
			{
				value = (result = factory.Invoke());
				return true;
			}
			return false;
		}
		internal static bool EnsureSegmentType<T>(out T result, IList<PathSegment> list, int index, Func<T> factory) where T : PathSegment
		{
			result = (list.get_Item(index) as T);
			if (result == null)
			{
				list.set_Item(index, result = factory.Invoke());
				return true;
			}
			return false;
		}
	}
}
